package org.sjs.dreamfly.player

import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.widget.Toast
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ui.StyledPlayerView.SHOW_BUFFERING_WHEN_PLAYING
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.sjs.dreamfly.R
import org.sjs.dreamfly.common.util.LogUtil
import org.sjs.dreamfly.common.util.PhemonUtils
import org.sjs.dreamfly.common.util.PlayUtil
import org.sjs.dreamfly.common.util.Router
import org.sjs.dreamfly.data.AppDataBase
import org.sjs.dreamfly.model.HistoryItem
import org.sjs.dreamfly.model.ResourceType
import org.sjs.dreamfly.model.VideoInfo
import org.sjs.dreamfly.widget.PlayerView

class MoviePlayerFragment : PlayerFragment(), Player.Listener, PlayerView.ActionListener {
    private lateinit var videoView: PlayerView
    private var exoPlayer: ExoPlayer? = null

    override fun requireLayoutId(): Int {
        return R.layout.fragment_player
    }

    override fun onPause() {
        super.onPause()
        saveHistory()
    }

    override fun onDestroy() {
        super.onDestroy()
        LogUtil.d("")
        exoPlayer?.release()
    }

    override fun onBindViews() {
        val view = requireView()
        videoView = view.findViewById(R.id.player_view)
    }
    @SuppressLint("ClickableViewAccessibility")
    override fun onInitViews() {
        videoView.addListener(this)
    }

    override fun onLoadData() {
        viewModel?.let { videoView.setDataProvider(it) }
        val index = arguments?.getInt(Router.KEY_INDEX)?:0
        playVideo(index)
    }

    override fun resumePlay() {
        if (exoPlayer?.isPlaying == false) {
            viewModel?.getVideoList()?.get(videoView.getIndex())?.let {
                playVideo(it)
            }
        }
    }

    override fun saveHistory(): Boolean {
        viewModel?.getVideoList()?.get(videoView.getIndex())?.parent?.let {
            val position = exoPlayer?.currentPosition?:0
            mainScope.launch(Dispatchers.IO) {
                AppDataBase.getDatabase(PhemonUtils.getApplication())
                    .historyDao()
                    .updateOrInsert(
                        HistoryItem(
                            movieInfo = it,
                            videoView.getIndex(),
                            position
                        ))
            }
            return true
        }
        return false
    }

    override fun onPlayerError(error: PlaybackException) {
        val index = videoView.getIndex()
        var message = error.message
        if (error.errorCode == PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS) {
            message = "播放地址已失效，正在重新获取"
        }
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
        viewModel?.getVideoList()?.get(index)?.videoUrl = null
        viewModel?.loadVideoUrl(index)
        videoView.setShowBuffering(SHOW_BUFFERING_WHEN_PLAYING)
    }

    override fun onBackButtonClick() {
        if (activity?.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
            activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        } else {
            activity?.supportFragmentManager?.beginTransaction()
                ?.remove(this@MoviePlayerFragment)?.commitNow()
        }
    }

    override fun onVideoItemClick(index: Int) {
        playVideo(index)
    }

    private fun playVideo(index: Int) {
        LogUtil.d("oldIndex: ${this.videoView.getIndex()}, newIndex: $index")
        if (this.videoView.getIndex() == index && exoPlayer?.isPlaying == true) {
            return
        }
        videoView.updatePlayList(index)
        val videoInfo = viewModel?.getVideoList()?.get(index)
        val url = videoInfo?.videoUrl
        exoPlayer?.pause()
        exoPlayer?.release()
        exoPlayer = null
        if (url.isNullOrEmpty()) {
            viewModel?.loadVideoUrl(index)
        } else {
            playVideo(videoInfo)
        }
    }

    private fun playVideo(videoInfo: VideoInfo) {
        mainScope.launch {
            val progress = getProgress(videoInfo)
            val newExoPlayer = if (videoInfo.videoUrl!!.contains(".m3u8")) {
                PlayUtil.playM3u8(requireContext(), videoView, videoInfo.videoUrl!!)
            } else {
                PlayUtil.playVideo(requireContext(), videoView, videoInfo.videoUrl!!, exoPlayer)
            }
            if (newExoPlayer?.equals(exoPlayer) == false) {
                exoPlayer = newExoPlayer
                exoPlayer?.addListener(this@MoviePlayerFragment)
            }
            exoPlayer?.playWhenReady = true
            exoPlayer?.seekTo(progress)
        }
    }

    private suspend fun getProgress(videoInfo: VideoInfo): Long {
        val historyItem = AppDataBase.getDatabase().historyDao().query(ResourceType.MOVIE, videoInfo.movieId!!).firstOrNull()
        if (historyItem?.movieProgress == videoInfo.nid - 1) {
            return historyItem.videoProgress
        } else return 0
    }
}

